package com.example.book_recommend.controller;

import com.example.book_recommend.entity.BookInfo;
import com.example.book_recommend.entity.SysToken;
import com.example.book_recommend.pojo.VueResultInfo;
import com.example.book_recommend.pojo.bookInfo.MyPageBook;
import com.example.book_recommend.pojo.storeInfo.MyPageSearch;
import com.example.book_recommend.pojo.storeInfo.VueBookInfo;
import com.example.book_recommend.service.BookService;
import com.example.book_recommend.service.impl.ShiroServiceImpl;
import com.example.book_recommend.utils.ResultFactory;
import com.example.book_recommend.algorithm.SchedueConfig;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;

@RestController
@EnableAutoConfiguration
@CrossOrigin
@RequestMapping("api/book")
public class BookController {
    @Autowired
    BookService bookService;

    @Autowired
    ShiroServiceImpl shiroService;

    /**
     * 这是一个示例！！！！！需要被完善！！！
     *
     * @param bookInfo
     * @param bindingResult
     * @return
     */
    @RequestMapping("/search")
    @ApiOperation(value = "post请求调用示例", notes = "invokePost说明", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "bookId", defaultValue = "1", required = true, paramType = "query", dataType = "Integer")
    })
    public VueResultInfo search(@RequestBody @Valid VueBookInfo bookInfo, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            String message = String.format("参数错误，详细信息[%s]。", Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
            return new VueResultInfo(1, message, null);
        }

        System.out.println(bookInfo.getBookId());
        return ResultFactory.buildSuccessResult(bookService.getBookInfo(bookInfo.getBookId()));
    }

    /**
     * 这是一个示例！！！！！需要被完善！！！
     *
     * @param bookInfo
     * @param bindingResult
     * @return
     */
    @RequestMapping("/searchByName")
    @ApiOperation(value = "post请求调用示例", notes = "invokePost说明", httpMethod = "POST")
    public VueResultInfo searchByName(@RequestBody @Valid BookInfo bookInfo, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            String message = String.format("参数错误，详细信息[%s]。", Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
            return new VueResultInfo(1, message, null);
        }

        System.out.println(bookInfo.getName());
        return ResultFactory.buildSuccessResult(bookService.getBookByName(bookInfo.getName()));
    }

    @RequestMapping("/searchBookByPage")
    @ApiOperation(value = "post请求调用示例", notes = "invokePost说明", httpMethod = "POST")
    public VueResultInfo searchBookByPage(@RequestBody @Valid MyPageBook myPageBook, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            String message = String.format("参数错误，详细信息[%s]。", Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
            return new VueResultInfo(1, message, null);
        }

        Integer page = myPageBook.getPage();
        Integer size = myPageBook.getSize();
        String name = "%" + myPageBook.getName() + "%";

        VueResultInfo vueResultInfo = new VueResultInfo(0, "", null);

        Subject subject = SecurityUtils.getSubject();
        boolean a = subject.hasRole("user");
        boolean b = subject.isPermitted("library");
        if (!subject.isPermitted("library")) {
            return new VueResultInfo(1, "你没有这个权限，可怜可怜", null);
        }

        vueResultInfo.setMessage("嗟，来拿");
        vueResultInfo.setData(bookService.getBookByPage(page, size, name));

        return vueResultInfo;
    }

    @RequestMapping("/searchBookByCategory")
    @ApiOperation(value = "通过类型查询书本", notes = "invokePost说明", httpMethod = "POST")
    public VueResultInfo searchBookByCategory(@RequestBody MyPageSearch myPageSearch, BindingResult bindingResult) {
        ArrayList<Integer> cartIds = myPageSearch.getCateIds();
        Integer page = myPageSearch.getPage();
        Integer size = myPageSearch.getSize();
        return ResultFactory.buildSuccessResult(bookService.getBookByCate(cartIds, page, size));
    }

    @RequestMapping("/getTop50/All")
    @ApiOperation(value = "通过类型查询书本", notes = "invokePost说明", httpMethod = "POST")
    public VueResultInfo getTop50All() {
        return ResultFactory.buildSuccessResult(bookService.getTop50All());
    }

    @RequestMapping("/getRecommendTrue")
    @ApiOperation(value = "通过类型查询书本", notes = "invokePost说明", httpMethod = "POST")
    public VueResultInfo getRecommendTrue(@RequestHeader("token") String token) {
        VueResultInfo vueResultInfo=new VueResultInfo(1,"error",null);
        SysToken sysToken = shiroService.findByToken(token);
        if (sysToken == null) {
            return new VueResultInfo(1, "您没登录", null);
        }
        Integer tokenUserId = sysToken.getUserId();
        List<RecommendedItem> recommendedItemList = null;
        try {
            recommendedItemList = SchedueConfig.recommender.recommend(tokenUserId, 7);
            int l = 10;
            int r = 0;
            List<BookInfo> bookInfos = new ArrayList<>();
            if(recommendedItemList != null){
                r = recommendedItemList.size();
                for (RecommendedItem recommendedItem : recommendedItemList) {
                    Long itemID = (Long) recommendedItem.getItemID();
                    BookInfo b = bookService.getBookInfo(itemID);
                    if(b!=null){bookInfos.add(b);}
                }
            }

            l = 10 - r;
            Random rr = new Random();
            int ran = rr.nextInt(1000);
            List<BookInfo> bookInfos2 = new ArrayList<>();
            bookInfos2 = bookService.getBookByPage((Integer) ran,(Integer) l, "%%");
            bookInfos.addAll(bookInfos2);
            return new VueResultInfo(0, "这是宁的xp", bookInfos);
        } catch (TasteException e) {
            Random r = new Random(1);
            int ran = r.nextInt(1000);
            vueResultInfo.setData(bookService.getBookByPage((Integer)ran, (Integer)10, "%%"));
            vueResultInfo.setCode(0);
            vueResultInfo.setMessage("你还没太多浏览记录，我给你瞎整了点推荐");
            return vueResultInfo;
        }
    }
}
